var gulp = require('gulp');
var browserify = require('gulp-browserify');
var cheerio = require('cheerio');
var cssmin = require('gulp-cssmin');
var download = require('gulp-download');
var exec = require('child_process').exec;
var less = require('gulp-less');
var rename = require("gulp-rename");
var uglify = require('gulp-uglify');
var connect = require('gulp-connect');
var request = require('request');
var fs = require('fs');
var wrap = require('wordwrap')(2, 80);

var port = 8080;

// this task downloads the lastest .js and .css from the 'parent'
// library that we are wrapping for react
gulp.task('download', function () {
	// download the .js file
	download('https://raw.githubusercontent.com/dangrossman/bootstrap-daterangepicker/master/daterangepicker.js')
		.pipe(gulp.dest('./lib/'));
	// download the .css files
	download('https://raw.githubusercontent.com/dangrossman/bootstrap-daterangepicker/master/daterangepicker.css')
		.pipe(gulp.dest('./css/'));
});

gulp.task('print-missing-options', function () {
	var downloadedOptions = require('./lib/get-options')(),
		options = fs.readFileSync('./lib/daterangepicker.js', 'utf-8')
			.toString().split(' ').filter(function (item) {
				return item.indexOf('options.') === 0;
			}).map(function (item) {
				return item.split('.')[1].split('[')[0].replace(/[^a-zA-Z0-9\<\>]/gi, '');
			});
	options = options.filter(function (item, index) {
		return options.indexOf(item) === index;
	}).sort().filter(function (item) {
		return downloadedOptions.indexOf(item) === -1;
	});
	console.log(options);
});

gulp.task('print-missing-proptypes', function () {
	var DatePicker = require('./lib/index');
	var picker = new DatePicker();
	var missing = picker.options.filter(function (o) {
		return !DatePicker.propTypes.hasOwnProperty(o);
	});
	console.log(missing);
});

gulp.task('get-options', function () {
	request('http://www.daterangepicker.com/', function (error, response, body) {
		var $ = cheerio.load(body);
		var options = $('#options ul li code').map(function () {
			return $(this).text().trim();
		}).get();
		// add options that aren't documented
		options.push('template');
		// de-dupe and sort
		options = options.filter(function (item, index) {
			return options.indexOf(item) === index;
		}).sort();
		fs.writeFile('./lib/get-options.js', [
			'"use strict";',
			'/* generated by gulpfile.js */',
			'module.exports = exports = function () {',
			'\treturn ' + JSON.stringify(options, null, '\t\t') + ';',
			'};'
		].join('\n'), 'utf-8');
		// fix options that contain html strings
		options = options.map(function (option) {
			return option.replace(/\</gi, '&lt;').replace(/\>/gi, '&gt;');
		});
		// update README.md
		var before = 'You can pass all the same props as the original plugin:',
			after = 'You can listen to the following 7 events:',
			readme = fs.readFileSync('./README.md').toString(),
			newReadme = readme.slice(0, readme.indexOf(before) + before.length) +
				'\n\n- **' +
				wrap(options.join(', ')).slice(2) +
				'**\n\n' +
				readme.slice(readme.indexOf(after));
		fs.writeFileSync('./README.md', newReadme, 'utf-8');
	});
});

gulp.task('lint', function () {
	exec([
			'node',
			'./node_modules/jsxhint/cli.js',
			//'--show-non-errors',
			'--config',
			'./.jshint',
			'./lib/*.js ./demo/src/*.js',
			'--exclude',
			'./lib/daterangepicker.js'
		].join(' '),
	function (err, stdout, stderr) {
		if (stdout) {
			console.log(stdout);
		}
	});
});

gulp.task('fonts', function () {
	gulp.src('./node_modules/bootstrap/dist/fonts/*')
		.pipe(gulp.dest('./demo/www/fonts/'));
});

gulp.task('app-content', function () {
	var content = fs.readFileSync('./demo/src/App.js', 'utf-8');
	fs.writeFileSync(
		'./demo/src/AppContent.js',
		[
			'/* autogenerated by gulpfile.js */',
			'exports.content = ' + JSON.stringify(content) + ';'
		].join('\n'),
		'utf-8'
	);
});

gulp.task('demo', function () {
	// styles
	gulp.src('./demo/src/less/demo.less')
		.pipe(less())
		.pipe(rename('demo.debug.css'))
		.pipe(gulp.dest('./demo/www/css/'))
		.pipe(cssmin())
		.pipe(rename('demo.min.css'))
		.pipe(gulp.dest('./demo/www/css/'));

	// scripts
	gulp.src('./demo/src/App.js')
		.pipe(browserify({
			debug: true,
			transform: ['babelify']
		}))
		.pipe(rename('demo.debug.js'))
		.pipe(gulp.dest('./demo/www/js/'))
		.pipe(uglify())
		.pipe(rename('demo.min.js'))
		.pipe(gulp.dest('./demo/www/js/'));
});

gulp.task('server', function() {
	connect.server({
		root: './demo/www',
		livereload: true,
		port: 8080
	});
});

gulp.task('watch', function () {
	gulp.watch(['./lib/index.js','./demo/src/**/*.js'], ['build']);
});

gulp.task('check', ['print-missing-options', 'print-missing-proptypes']);
gulp.task('update', ['download', 'get-options']);
gulp.task('build', ['lint', 'fonts', 'app-content', 'demo']);
gulp.task('default', ['build', 'server', 'watch']);

//handle errors
process.on('uncaughtException', function (e) {
	console.error(e);
});
